import { ASelectValueType } from "@/components/SelfComp/ASelect";
import { AppItem } from '@/types/app';
import { DataItem } from "@/types/global";
import { getButton, getButtonCode } from "./authority";

/**
 * 生成唯一标识符
 * @returns 比如 748eea29-f842-4af9-a552-e1e1aa3ed979
 */
export function guid(): string {
  function S4(): string {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  }
  return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4()+ "-" + S4() + S4() + S4());
}

// 表单布局
export const formLayout = 'horizontal';
// 基础表单项布局
export const basicFormItemLayout = {
  // label占宽度
  labelCol: { span: 8 },
  // 输入组件占宽度
  wrapperCol: { span: 8},
};

// 长输入组件的布局
export const basicFormItemLangLayout = {
  // label占宽度
  labelCol: { span: 8 },
  // 输入组件占宽度
  wrapperCol: { span: 16 },
};

// 适用于Col的span设置为24的栏位超长的表单项
export const maxFormItemLayout = {
  // label占宽度
  labelCol: { span: 4 },
  // 输入组件占宽度
  wrapperCol: { span: 16},
};
// 适用于Modal中的表单项
export const modalFormItemLayout = {
  // label占宽度
  labelCol: { span: 8 },
  // 输入组件占宽度
  wrapperCol: { span: 12 },
}

// 注意将Col的span设置为24
export const maxModalFormItemLayout = {
  // label占宽度
  labelCol: { span: 4 },
  // 输入组件占宽度
  wrapperCol: { span: 18 },
};

/**
 * 根据数据构造下拉框选项
 * @param arr 数组，数组元素为{key: xx, value: xx}的形式
 * @param {string} type 下拉框选项类型，为1时，展示key-value，为2时，只展示value
 * @returns 返回拼好的Option数组
 */
export const createSelectOptions = (dataSource: DataItem[], type: string) => {
  if (!dataSource) {
    return new Array<ASelectValueType>(0);
  }
  // 1、展示key-value形式，但取值是key
  // 2、展示value形式，但取值是key
  // 3、展示key-value形式，但取值是value
  // 4、展示value形式，但取值是value
  return dataSource.map(item => {
    if (type === '1') {
      const option: ASelectValueType = {
        label: `${item.key}-${item.value}`,
        value: item.key
      };
      return option;
    } else if (type === '2') {
      const option: ASelectValueType = {
        label: item.value,
        value: item.key
      };
      return option;
    } else if (type === '3') {
      const option: ASelectValueType = {
        label: `${item.key}-${item.value}`,
        value: item.value
      };
      return option;
    } else {
      const option: ASelectValueType = {
        label: item.value,
        value: item.value
      };
      return option;
    }
  });
}

/**
 * 根据key获取集合中对应的value值
 * @param items 数据集合，元素以{key:'1',value:'2'}形式存在
 * @param key key值
 * @param type value值的返回形式，1-[value]，2-[key-value]，默认为1
 * @returns 对应的value值
 */
export const getItemValue = (items: DataItem[], key: string, type: string = '1'): string => {
  if (!items) {
    return key;
  }
  let tmp = key;
  const len = items.length;
  // console.info('getItemValue', len);
  for (let i = 0; i < len; i += 1) {
    const item = items[i];
    // console.info('getItemValue', item);
    if (item.key === key) {
      tmp = item.value;
      break;
    }
  }
  if (type === '2') {
    tmp = `${key}-${tmp}`;
  }
  return tmp;
}

/**
 * 判断集合中是否包含key
 * @param items 数据集合，元素以{key:'1',value:'2'}形式存在
 * @param key key值
 * @returns true-包含
 */
export const hasKey = (items: DataItem[], key: string): boolean => {
  if (!items) {
    return false;
  }
  if (!key) {
    return false;
  }
  let tmp = false;
  const len = items.length;
  for (let i = 0; i < len; i += 1) {
    const item = items[i];
    if (item.key === key) {
      tmp = true;
      break;
    }
  }
  return tmp;
}

/**
 * 根据页面代码和按钮代码，判断是否有权限
 * @param {string} pageCode 页面代码
 * @param {string} btnCode 按钮代码
 * @returns 是否有权限，true-有按钮权限
 */
export const hasButtonPermission = (pageCode: string, btnCode: string) => {
  // 获取页面代码的按钮列表
  const btns = getButton(pageCode) || [];
  if (!btns || btns.length === 0) {
    return false;
  }
  return btns.some(btn => {
    const code = getButtonCode(btn);
    return code === btnCode
  });
}

/**
 * 编码，先将对象转成json字符串，然后url编码，最后base64编码
 * @param {*} data 对象参数
 */
export const encodeData = (data: any) => {
  // base64不支持中文，所以先url编码
  const encode = window.encodeURIComponent(JSON.stringify(data));
  const encodeStr = window.btoa(encode);
  return encodeStr;
}

/**
 * 编码，先将编码字符串，通过base64编码，然后url解码，最后转成对象
 * @param {*} encodeStr 编码后的字符串
 */
export const decodeData = (encodeStr: string) => {
  // 先base64解码，在url解码
  const baseStr = window.atob(encodeStr);
  const decodeStr = window.decodeURIComponent(baseStr);
  // 转对象
  const decodeObj = JSON.parse(decodeStr);
  return decodeObj;
}

/**
 * 级联组件数据类型
 */
export type CascaderOption = {
  value: string;
  label: string;
  children?: CascaderOption[];
}

/**
 * 一个空的级联组件
 */
const EMPTY_CASCADER: CascaderOption[] = [];

/**
 * 转换为级联组件数据
 */
export const generateCascaderOptions = (appList: AppItem[], systemData: DataItem[], clusterData: DataItem[]): CascaderOption[] => {
  if (!appList) {
    return EMPTY_CASCADER;
  }
  // 将列表数据转换为级联数据
  const len = appList.length;
  const options: CascaderOption[] = [];
  const keyExists: string[] = [];
  for (let i = 0; i < len; i += 1) {
    const appItem = appList[i];
    const { systemCode, cluster, appCode, appName } = appItem;
    const keyStr = `${systemCode}-${cluster}`;
    const clusterName = getItemValue(clusterData, cluster);
    if (keyExists.indexOf(keyStr) > -1) {
      // 首先判断系统，集群是否存在
      // 存在，则认为级联数组中已经有了，直接获取
      options.forEach((item, _index) => {
        if (item.value === systemCode) {
          // 找到对应元素
          const clstSize = item.children!.length;
          for (let j = 0; j < clstSize; j += 1) {
            const clstItem = item.children![j];
            if (clstItem.value === cluster) {
              // 找到了对应的节点
              // 添加应用
              const appItem = createNode(appCode, appName);
              clstItem.children!.push(appItem);
            }
          }
        }
      })
    } else if (keyExists.indexOf(systemCode) > -1) {
      // 系统已存在
      // 添加集群和应用
      options.forEach((item, _index) => {
        if (item.value === systemCode) {
          // 找到对应元素
          const appItem = createNode(appCode, appName);
          const clstItem = createNode(cluster, clusterName, true);
          clstItem.children!.push(appItem);
          item.children!.push(clstItem);
        }
      });
    } else {
      // 系统不存在
      // 添加系统，集群，应用
      const systemName = getItemValue(systemData, systemCode);
      const appItem = createNode(appCode, appName);
      const clstItem = createNode(cluster, clusterName, true);
      clstItem.children!.push(appItem);
      const systemItem = createNode(systemCode, systemName, true);
      systemItem.children!.push(clstItem);
      options.push(systemItem);
    }
    keyExists.push(systemCode);
    keyExists.push(keyStr);
  }
  return options;
}

const createNode = (value: string, label: string, hasChild: boolean = false): CascaderOption => {
  if (hasChild) {
    return {
      value,
      label,
      children: []
    }
  }
  return {
    value,
    label
  }
}